<?php
/**
 * Description
 *
 * PHP version 7
 *
 * @category Custom
 * @package  Custom
 * @author   ryu <mo5467@126.com>
 * @date     2020-04-29 01:10:55
 * @lastTime 2020-04-29 01:14:09
 * @license  https://opensource.org/licenses/MIT MIT License
 * @link     none
 */

namespace Design\Behavioral\TemplateMethod;

abstract class Journey
{

    /**
     * @var string[]
     */
    private $thingsToDo = [];


    /**
     * This is the public service provided by this class and its subclasses.
     * Notice it is final to "freeze" the global behavior of algorithm.
     * If you want to override this contract, make an interface with only takeATrip()
     * and subclass it.
     */
    final public function takeATrip()
    {
        $this->thingsToDo[] = $this->buyAFlight();
        $this->thingsToDo[] = $this->takePlane();
        $this->thingsToDo[] = $this->enjoyVacation();
        $buyGift            = $this->buyGift();

        if ($buyGift !== null) {
            $this->thingsToDo[] = $buyGift;
        }

        $this->thingsToDo[] = $this->takePlane();

    }//end takeATrip()


    /**
     * This method must be implemented, this is the key-feature of this pattern.
     */
    abstract protected function enjoyVacation(): string;


    /**
     * This method is also part of the algorithm but it is optional.
     * You can override it only if you need to
     */
    protected function buyGift(): ?string
    {
        return null;

    }//end buyGift()


    private function buyAFlight(): string
    {
        return 'Buy a flight ticket';

    }//end buyAFlight()


    private function takePlane(): string
    {
        return 'Taking the plane';

    }//end takePlane()


    /**
     * @return string[]
     */
    public function getThingsToDo(): array
    {
        return $this->thingsToDo;

    }//end getThingsToDo()


}//end class
